﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms.VisualStyles;
using UpdaterForm.Annotations;
using UpdaterForm.CustomTreeView;

namespace UpdaterForm
{
    public class Update : INotifyPropertyChanged
    {
        public UpdateData UpdateData { get; set; }
        public Boolean Custom { get; set; }
        public ATreeNode UpdateFolder { get; set; }
        public List<ATreeNode> Content { get; set; }
        private AppData _target;

        private UpdateLog _log;
        public UpdateLog Log
        {
            get { return _log; }
            set
            {
                _log = value;
                OnPropertyChanged("Log");
            }
        }

        private UpdateState _isInstalled;
        public UpdateState IsInstalled
        {
            get { return _isInstalled; }
            set
            {
                _isInstalled = value;
                OnPropertyChanged("IsInstalled");
            }
        }

        private bool _inProgress;
        public bool InProgress{
            get { return  _inProgress; }
            set
            {
                _inProgress = value;
                OnPropertyChanged("InProgress");
            }
        }

        public Update(DirectoryInfo source, AppData target)
        {
            InProgress = false;
            _target = target;
            UpdateData = new UpdateData(source);
            UpdateFolder = new FolderNode(source, _target.InstallationPath);
            UpdateFolder.Name = UpdateData.Name;
            UpdateFolder.Initialize();
            Content = UpdateFolder.Children;
            IsInstalled = UpdateData.Name.Equals(target.CurrentVersion) ? UpdateState.CurrentVesion : target.History.GetStatus(UpdateData.Name);
            Log = _target.History.GetLog(UpdateData.Name);
        }

        public void Install()
        {
            InProgress = true;
            if (Log == null)
            {
                //Esli loga netu to sozdadim ego i dobavim
                Log = new UpdateLog
                {
                    Name = UpdateData.Name,
                    Time = DateTime.Now
                };
                _target.History.Logs.Add(Log);
            }

            UpdateState state;
            try
            {
                foreach (var node in Content)
                    node.Apply(Custom);


                state = Custom
                    ? (Log.TransferedFiles.Count == UpdateData.Lenght
                        ? UpdateState.FullyInstalled
                        : UpdateState.PartlyInstalled)
                    : UpdateState.FullyInstalled;
                Log.FailReason = null;

            }
            catch (Exception e)
            {
                state = UpdateState.InstallFailed;
                Log.FailReason = e.Message;
            }

            Log.State = state;
            Log.Time = DateTime.Now;
            IsInstalled = state;

            OnPropertyChanged("Log");
            InProgress = false;
            _target.CurrentVersion = UpdateData.Name;
        }

        public event PropertyChangedEventHandler PropertyChanged;

        [NotifyPropertyChangedInvocator]
        protected virtual void OnPropertyChanged(string propertyName)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}
